﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Profile;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.member;
using umbraco;
using umbraco.presentation.nodeFactory;
using Commerce.Common;

namespace CommerceForUmbraco.usercontrols.usercontrols.commerce
{
    public partial class PWRegisterUser : System.Web.UI.UserControl
    {
        // Umbraco property to set to make this control be able to be
        // re-used to edit/update their information...
        public bool IsUpdatingExistingMemember
        {
            get
            {
                if (ViewState["IsUpdatingExistingMemember"] == null)
                {
                    ViewState["IsUpdatingExistingMemember"] = false;
                }

                return Convert.ToBoolean(ViewState["IsUpdatingExistingMemember"]);
            }
            set { ViewState["IsUpdatingExistingMemember"] = value; }
        }

        public string ThankYouPage { get; set; }
        
        protected void Page_Load(object sender, EventArgs e)
        {
            this.ctrlAdditionalValidationMessageLabel.Text = "";


            Node currPage = Node.GetCurrent();
            Document currPageDoc = new Document(currPage.Id);
            if (currPageDoc.getProperty("userCreationSuccessMessage") != null)
            {
                this.ctrlSuccessMessageLabel.Text = currPageDoc.getProperty("userCreationSuccessMessage").Value.ToString();
            }
            this.ctrlSuccessMessageLabel.Visible = false;

            
            if (this.IsPostBack == false)
            {
                if (this.IsUpdatingExistingMemember)
                {
                    this.ctrlRegisterBtn.Visible = false;
                    this.ctrlUpdateBtn.Visible = true;

                    this.panelUserPassword.Visible = false;

                    Member currentMember = Member.GetCurrentMember();
                    if (currentMember == null)
                    {
                        this.ctrlInputPanel.Visible = false;
                        this.ctrlAdditionalValidationMessageLabel.Text = "Sorry, unable to edit your membership info - no current member detected as logged in at this time.";
                        return;
                    }

                    InitWithCurrentMember(currentMember);
                }
                else
                {
                    this.ctrlRegisterBtn.Visible = true;
                    this.ctrlUpdateBtn.Visible = false;

                    Session["PreviousUserName"] = Utility.GetUserName();
                }

                this.ctrlFirstNameTextBox.Focus();
            }
        }

        private void InitWithCurrentMember(Member currentMember)
        {
            // Personal
            this.ctrlFirstNameTextBox.Text      = currentMember.getProperty("shippingFirstName").Value as string;
            this.ctrlLastNameTextBox.Text       = currentMember.getProperty("shippingLastName").Value as string;
            this.ctrlEmailTextBox.Text          = currentMember.getProperty("shippingEmail").Value as string;
            int optId = 0;
            if (Int32.TryParse(currentMember.getProperty("optIn").Value.ToString(), out optId))
            {
                this.ctrlNewsLetterCheckBox.Checked = (optId == 1 ? true : false);
            }
            int billingSameAsShipping = 0;
            if (Int32.TryParse(currentMember.getProperty("billingSameAsShipping").Value.ToString(), out billingSameAsShipping))
            {
                this.cbUseSameBillingInfoAsShipping.Checked = (billingSameAsShipping == 1 ? true : false);
            }

            // Shipping
            this.ctrlShippingAddress1TextBox.Text   = currentMember.getProperty("shippingAddress1").Value as string;
            this.ctrlShippingAddress2TextBox.Text   = currentMember.getProperty("shippingAddress2").Value as string;
            this.ctrlShippingCityTextBox.Text       = currentMember.getProperty("shippingCity").Value as string;
            this.ctrlShippingState.SelectedValue    = currentMember.getProperty("shippingStateOrRegion").Value as string;
            this.ctrlShippingZipCode.Text           = currentMember.getProperty("shippingZip").Value as string;
            this.ctrlShippingCountry.SelectedValue  = currentMember.getProperty("shippingCountry").Value as string;

            if (!cbUseSameBillingInfoAsShipping.Checked)
            {
                this.BillingInfoFieldsPanel.CssClass = "billinginfofields";
            }


            // Billing
            this.ctrlCityTextBox.Text               = currentMember.getProperty("billingCity").Value as string;
            this.ctrlPostalCodeTextBox.Text         = currentMember.getProperty("billingZip").Value as string;
            this.ctrlStateProvince.SelectedValue    = currentMember.getProperty("billingStateOrRegion").Value as string;
            this.ctrlStreetAddressTextBox.Text      = currentMember.getProperty("billingAddress1").Value as string;
            this.ctrlTelephoneNumberTextBox.Text    = currentMember.getProperty("billingPhone").Value as string;

            this.ctrlPasswordBox.Text = currentMember.Password;
            this.ctrlPasswordConfirmBox.Text = currentMember.Password;

            // can't change their user name!
            this.ctrlUserNameTextBox.Text = currentMember.LoginName;
            this.ctrlUserNameTextBox.Enabled = false;

            // NOTE: there might be duplicates in the DD lists
            // and only one selection is possible for DD lists, hence the hasSelection flag
            bool hasSelection = false;

            this.ctrlCountryDDList.ClearSelection();
            string countryCode = currentMember.getProperty("billingCountry").Value as string;
            hasSelection = false;
            foreach (ListItem li in this.ctrlCountryDDList.Items)
            {
                if (li.Value == countryCode && hasSelection == false)
                {
                    li.Selected = true;
                    hasSelection = true;
                    break;
                }
            }
        }

        protected void ctrlRegisterBtn_Click(object sender, EventArgs e)
        {
            CreateOrUpdateMember();
        }
        
        protected void ctrlUpdateBtn_Click(object sender, EventArgs e)
        {
            CreateOrUpdateMember();
        }

        private void CreateOrUpdateMember()
        {
            if (this.ctrlShippingCountry.SelectedItem.Value == "")
            {
                this.ctrlAdditionalValidationMessageLabel.Text = "Please select a Country";
                return;
            }

            if ((this.ctrlPasswordBox.Text == "" ||
                 this.ctrlPasswordConfirmBox.Text == "") &&
                 this.IsUpdatingExistingMemember == false
                )
            {
                this.ctrlAdditionalValidationMessageLabel.Text = "You must enter your password and password confirmation.";
                return;
            }

            if ( (this.ctrlPasswordBox.Text != this.ctrlPasswordConfirmBox.Text) &&
                 this.IsUpdatingExistingMemember == false
                )
            {
                this.ctrlAdditionalValidationMessageLabel.Text = "Your password and password confirmation are not the same.";
                return;
            }

            if ( this.IsUpdatingExistingMemember == false )
            {
                PasswordScore score = PasswordAdvisor.CheckStrength(ctrlPasswordBox.Text);
                Int32 i = (Int32)score;

                if (i < 2)
                {
                    this.ctrlAdditionalValidationMessageLabel.Text = "Password strength is too weak.  Please enter a password with at least 6 characters and we recommend a mix of letters, numbers, and symbols.";
                    return;
                }
            }


            if (this.IsUpdatingExistingMemember == false)
            {
                if (Member.GetMemberFromLoginName(this.ctrlUserNameTextBox.Text.Trim()) != null)
                {
                    this.ctrlAdditionalValidationMessageLabel.Text = "Sorry, there is already a customer account registered with this USER NAME.";
                    return;
                }

                if (Member.GetMemberFromEmail(this.ctrlEmailTextBox.Text.Trim()) != null)
                {
                    this.ctrlAdditionalValidationMessageLabel.Text = "Sorry, there is already a customer account registered with this EMAIL.";
                    return;
                }
            }

            string processingContext = "";

            try
            {
                processingContext = "Attempting to find the 'Customer' member type.";

                MemberType customerMemberType = MemberType.GetByAlias("Customer");
                if (customerMemberType == null)
                {
                    throw new Exception("Unable to find the 'Customer' member type alias.");
                }

                processingContext = "Attempting to find or make a new customer record in umbraco.";
                Member member = null;

                if (this.IsUpdatingExistingMemember == false)
                {
                    processingContext = "Attempting to create the umbraco member profile information.";
                    Member newMember = Member.MakeNew(this.ctrlUserNameTextBox.Text.Trim(), customerMemberType, new umbraco.BusinessLogic.User(0));

                    if (newMember == null)
                    {
                        throw new Exception("Unable to create new member: " + this.ctrlUserNameTextBox.Text.Trim());
                    }
                }

                member = Member.GetMemberFromLoginName(this.ctrlUserNameTextBox.Text.Trim());

                // Personal
                member.getProperty("shippingFirstName").Value = this.ctrlFirstNameTextBox.Text.Trim();
                member.getProperty("shippingLastName").Value = this.ctrlLastNameTextBox.Text.Trim();
                member.getProperty("shippingEmail").Value = this.ctrlEmailTextBox.Text.Trim();

                // Shipping
                member.getProperty("shippingAddress1").Value = this.ctrlShippingAddress1TextBox.Text.Trim();
                member.getProperty("shippingAddress2").Value = this.ctrlShippingAddress2TextBox.Text.Trim();
                member.getProperty("shippingZip").Value = this.ctrlShippingZipCode.Text.Trim();
                member.getProperty("shippingCity").Value = this.ctrlShippingCityTextBox.Text.Trim();
                member.getProperty("shippingStateOrRegion").Value = this.ctrlShippingState.SelectedItem.Value;
                member.getProperty("shippingCountry").Value = this.ctrlShippingCountry.SelectedItem.Value;
                member.getProperty("shippingPhone").Value = this.ctrlShippingPhone.Text.Trim();
                member.getProperty("shippingLastUpdate").Value = DateTime.Today;

                // Billing
                member.getProperty("billingSameAsShipping").Value = this.cbUseSameBillingInfoAsShipping.Checked ? "1" : "0";

                if (!this.cbUseSameBillingInfoAsShipping.Checked)
                {
                    member.getProperty("billingFirstName").Value = this.ctrlFirstNameTextBox.Text.Trim();
                    member.getProperty("billingLastName").Value = this.ctrlLastNameTextBox.Text.Trim();
                    member.getProperty("billingAddress1").Value = this.ctrlStreetAddressTextBox.Text.Trim();
                    member.getProperty("billingEmail").Value = this.ctrlEmailTextBox.Text.Trim();
                    member.getProperty("billingZip").Value = this.ctrlPostalCodeTextBox.Text.Trim();
                    member.getProperty("billingCity").Value = this.ctrlCityTextBox.Text.Trim();
                    member.getProperty("billingStateOrRegion").Value = this.ctrlStateProvince.SelectedItem.Value;
                    member.getProperty("billingCountry").Value = this.ctrlCountryDDList.SelectedItem.Value;
                    member.getProperty("billingPhone").Value = this.ctrlTelephoneNumberTextBox.Text.Trim();
                    member.getProperty("billingLastUpdate").Value = DateTime.Today;
                }

                member.getProperty("optIn").Value = this.ctrlNewsLetterCheckBox.Checked ? "1" : "0";

                member.Email = this.ctrlEmailTextBox.Text.Trim();
                if (this.IsUpdatingExistingMemember == false)
                {
                    member.Password = this.ctrlPasswordBox.Text;
                }
                member.Text = this.ctrlUserNameTextBox.Text.Trim();

                //// Update these dates to "now"
                //member.getProperty("shippingLastUpdate").Value = DateTime.Now.ToString();
                //member.getProperty("billingLastUpdate").Value = DateTime.Now.ToString();

                if (this.IsUpdatingExistingMemember == false)
                {
                    processingContext = "Attempting to find and assign the 'Customers' group to member.";
                    MemberGroup customersGroup = MemberGroup.GetByName("Customers");
                    if (customersGroup == null)
                    {
                        throw new Exception("Unable to find the 'Customers' group in umbraco.");
                    }
                    else
                    {
                        member.AddGroup(customersGroup.Id);
                    }
                }

                processingContext = "Attempting to save umbraco member profile properties.";
                member.Save();
   
                // TODO: not sure if this is necessary - seems to log the user in...
                // Add this member to the cache so they stick around...?
                if (this.IsUpdatingExistingMemember == false)
                {
                    // Migrate the cart
                    string prevUserName = (string)(Session["PreviousUserName"]);

                    string sUserName = this.ctrlEmailTextBox.Text.Trim();

                    if (string.IsNullOrEmpty(sUserName) == false)
                    {
                        OrderController.MigrateCart(prevUserName, sUserName);
                    }

                    Member.AddMemberToCache(member);

                    //to user saying thank you
                    MessagingController.SendNewAccountEmail(member.Text, member.Email);
                }
            }
            catch (Exception x)
            {
                this.ctrlAdditionalValidationMessageLabel.Text = string.Format("Error - unable to create or modify your customer account. Processing Context: {0} Exception Details: {1}", processingContext, x.Message);
                return;
            }

            // SUCCESS!
            if (this.IsUpdatingExistingMemember == false)
            {
                this.ctrlInputPanel.Visible = false;
                this.ctrlSuccessMessageLabel.Visible = true;

                if (ThankYouPage.Length > 0)
                {
                    int thankyouNode = -1;
                    if( Int32.TryParse(ThankYouPage, out thankyouNode) )
                    {
                        Node currPage = new Node(thankyouNode);
                        Response.Redirect(currPage.NiceUrl);
                    }
                }
                //this.ctrlSuccessMessageLabel.Text = "Success!  Your membership account was successfully created.";
            }
            else
            {
                this.ctrlSuccessMessageLabel.Visible = true;

                this.ctrlSuccessMessageLabel.Text = "Success!  Your membership account was successfully updated.";
            }
        }

    }
}